import networkx as nx
import matplotlib.pyplot as plt
import operator
import torch
import scipy as sp

def General_Page_Rank(G, d, epsilon):
    N = G.number_of_nodes()
    r_old = torch.full([N], 1.0/N, dtype = torch.float32)
    M = torch.tensor(nx.adjacency_matrix(G).todense(), dtype = torch.float32).T
    for j in range(N):
        sum_j = sum(M[:,j])
        for i in range(N):
            M[i, j] /= sum_j
    r_new = d * torch.mv(M, r_old) + ((1.0-d) / N) * torch.full([N], 1.0, dtype = torch.float32)
    number_of_iter = 0
    while torch.norm(r_new - r_old) > epsilon:
        r_old[:] = r_new
        r_new[:] = d * torch.mv(M, r_old) + ((1.0-d) / N) * torch.full([N], 1.0)
        number_of_iter += 1
    return [r_new, number_of_iter]